package n90_JDK线程池;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;

import static utils.Sleeper.sleep;

/**
 * @author fu
 * @date 2022-03-28 22:52
 * 概要：
 * ---------------------------------------------------------------
 * |                                                              |
 * |                  |
 * |                                                             |
 * |=============================================================
 */
@Slf4j(topic = "c.T1")
public class T1_Executors工厂方法 {

    public static void main(String[] args) {
//        _test1_newFixedThreadPool();
//        _test2_newCachedThreadPool();
        _test3_newSingleThreadExecutor();

    }


    /**
     * 固定线程池大小
     * 使用：任务量已知，相对耗时的任务
     * 特点：核心线程==最大线程数；因此没有救急线程被创建，也无需超时时间
     *      阻塞队列无界，可创建任意数量任务
     */
    private static void _test1_newFixedThreadPool() {
        final ExecutorService pool = Executors.newFixedThreadPool(2, new ThreadFactory() {
            private AtomicInteger t = new AtomicInteger(1);
            @Override
            public Thread newThread(Runnable r) {
                return new Thread(r,"线程" + t.getAndIncrement());
            }
        });

        log.debug("begin...");
        pool.execute(()->{
            log.debug("1---");
            sleep(2);
        });
        pool.execute(()->{
            log.debug("2---");
            sleep(2);
        });
        pool.execute(()->{
            log.debug("3---");
        });
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> HEAD
   /*
        22:54:30.560 [pool-1-thread-2] c.T1 - 2---
        22:54:30.560 [pool-1-thread-1] c.T1 - 1---
        22:54:30.562 [pool-1-thread-2] c.T1 - 3---
    */
//===============================
/*
        22:33:34.917 [线程2] c.T1 - 2---
        22:33:34.917 [线程1] c.T1 - 1---
        22:33:34.919 [线程2] c.T1 - 3---
*/
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< END
    }


    /**
     * 带缓冲功能的线程池
     *  有线程来了 才给给任务 【相当于 有任务才创建新的线程】
     */
    private static void _test2_newCachedThreadPool(){

        SynchronousQueue<Integer> integers = new SynchronousQueue<>();
        new Thread(() -> {
            try {
                log.debug("putting {}  直接放放不进去 阻塞中......", 1);
                integers.put(1);
                log.debug("{} putted... 有线程取走了，才算结束！", 1);
                log.debug("putting...{} ", 2);
                integers.put(2);
                log.debug("{} putted...", 2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"AA ").start();

        // 一秒后
        sleep(1);
        new Thread(() -> {
            try {
                log.debug("taking {}", 1);
                integers.take();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"BB").start();

        // 这里是 两秒后，因为上面已经有一秒了
        sleep(1);
        new Thread(() -> {
            try {
                log.debug("taking {}", 2);
                integers.take();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            log.debug("取走了 执行完了...  [AA线程]才执行完！");
        },"CC").start();
    }



    /**
     * 单线程 执行器 [只创建一个线程 ，一个一个执行！]
     */
    private static void _test3_newSingleThreadExecutor(){
        final ExecutorService pool = Executors.newSingleThreadExecutor();

        log.debug("beigin......");
        // 线程报错结束了 ，但是下面还会继续创建
        pool.execute(()->{
            sleep(1);
            log.debug("1");
            int i = 1/0;
        });

        pool.execute(()->{
            sleep(2);
            log.debug("2");
        });
        pool.execute(()->{
            sleep(3);
            log.debug("3");
        });
    }
}
